﻿using System;
using System.Drawing;
using System.Windows.Forms;
using System.Collections.Generic;
//=========================================
//
// 作 者：LsongStudio
// 邮 箱：song940@gmail.com
// 博 客：http://lsongs.host.sk/
// 时 间：2010-11-24 18:37:56
//
//=========================================
namespace VirusCleaner.Controls
{
    //msg=0x115   (WM_VSCROLL)横向滚动     
    //msg=0x114   (WM_HSCROLL)竖向滚动   
    ///   <summary>   
    ///   CListView   的摘要说明。
    ///   </summary>   
    public class CListView : ListView
    {
        #region 变量
        /// <summary>
        /// 当前显示列表
        /// </summary>
        private Control _currentCtrl;

        /// <summary>
        /// 存储需要显示的控件列表
        /// </summary>
        private readonly SortedList<int, object> _mCtrls;
        /// <summary>
        /// 全局被选中的列索引
        /// </summary>
        int _columnIndex = 99999;

        #endregion
        #region 方法
        /// <summary>
        /// 添加需要显示的控件
        /// </summary>
        /// <param name="ctr">显示的控件(目前只支持textbox和combox)</param>
        /// <param name="columnIndex">在listview中的列索引</param>
        public void AddDisControl(Control ctr, int columnIndex)
        {
            if (_mCtrls.ContainsKey(columnIndex))
            {
                //MessageBox.Show("已经包含所选的" + ctr.ToString());
                return;
            }
            ctr.Visible = true;
            _mCtrls.Add(columnIndex, (object)ctr);
            this.Controls.Add(ctr);
        }
        private void EditItem(int index, ListViewItem.ListViewSubItem sb)
        {
            if (this.SelectedItems.Count <= 0)
            {
                return;
            }
            int currentSelectColumnIndex = _mCtrls.IndexOfKey(index);
            if (currentSelectColumnIndex == -1)
            {
                return;
            }
            _currentCtrl = (Control)_mCtrls.Values[currentSelectColumnIndex];
            ListViewItem item = this.SelectedItems[0];
            Rectangle rect = sb.Bounds;
            Rectangle _rect = new Rectangle(rect.Right - this.Columns[index].Width, rect.Top, this.Columns[index].Width, rect.Height);
            _currentCtrl.Bounds = _rect;
            _currentCtrl.BringToFront();
            _currentCtrl.Text = item.SubItems[index].Text;
            _currentCtrl.TextChanged += new EventHandler(CtrTextChanged);
            _currentCtrl.Leave += new EventHandler(CtrLeave);

            _currentCtrl.Visible = true;
            _currentCtrl.Tag = item;
            _currentCtrl.Select();
        }
        #endregion
        #region 构造函数
        public CListView()
        {
            _mCtrls = null;
            _currentCtrl = null;
            SetStyle(ControlStyles.DoubleBuffer | ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
            UpdateStyles();
             _mCtrls = new SortedList<int,object>();
         }
        #endregion
        #region 重载事件
        protected override void OnKeyDown(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.F2)
            {
                Point tmpPoint = this.PointToClient(Cursor.Position);
                ListViewItem item = this.GetItemAt(tmpPoint.X, tmpPoint.Y);
                if (item != null)
                {
                    ListViewItem.ListViewSubItem sb = item.GetSubItemAt(tmpPoint.X, tmpPoint.Y);
                    _columnIndex = item.SubItems.IndexOf(sb);
                    if (tmpPoint.X > this.Columns[0].Width && tmpPoint.X < this.Width)
                    {
                        EditItem(_columnIndex, sb);
                    }
                }
            }
            base.OnKeyDown(e);
        }

        protected override void OnSelectedIndexChanged(EventArgs e)
        {
            if (this._currentCtrl != null)
            {
                this._currentCtrl.Visible = false;
            }
            base.OnSelectedIndexChanged(e);
        }

        protected override void OnClick(EventArgs e)
        {
            if (this.SelectedItems.Count == 0)
            {
                return;
            }
            Point tmpPoint = this.PointToClient(Cursor.Position);
            ListViewItem item = this.GetItemAt(tmpPoint.X, tmpPoint.Y);
            if (this.SelectedItems.Count != 0 && item == null)
            {
                item = this.SelectedItems[0];
            }
            if (item != null)
            {
                ListViewItem.ListViewSubItem sb = item.GetSubItemAt(tmpPoint.X, tmpPoint.Y);
                _columnIndex = item.SubItems.IndexOf(sb);
                if (tmpPoint.X > this.Columns[0].Width && tmpPoint.X < this.Width)
                {
                    EditItem(_columnIndex, sb);
                }
            }
            base.OnDoubleClick(e);
        }

        protected override void WndProc(ref   Message m)
        {
            if (m.Msg == 0x115 )
            {
                if (_currentCtrl != null)
                {
                    _currentCtrl.Visible = false;
                }
            }
            if ( m.Msg == 0x114)
            {
                if (_currentCtrl != null)
                {
                    _currentCtrl.Visible = false;
                }
            }
            base.WndProc(ref   m);
        }
        #endregion
        #region 控件事件
        private void CtrLeave(object sender, EventArgs e)
        {
            if (sender is Control)
            {
                ((Control)sender).TextChanged -= new EventHandler(CtrTextChanged);
                (sender as Control).Visible = false;
            }
        }
        public void CtrSelectedIndexChanged(object sender, EventArgs e)
        {
            if (((Control) sender).Tag is ListViewItem)
            {
                (((Control)sender).Tag as ListViewItem).SubItems[_columnIndex].Text = ((Control)sender).Text; ;
            }
        }
        private void CtrTextChanged(object sender, EventArgs e)
        {
           
            if (((Control) sender).Tag is ListViewItem)
            {
                (((Control)sender).Tag as ListViewItem).SubItems[_columnIndex].Text = ((Control)sender).Text;
            }

        }
        #endregion
        #region listview进度条显示
        //C# listview进度条显示
        private Color _mProgressColor = Color.Red;

        public Color ProgressColor
        {
            get
            {
                return this._mProgressColor;
            }
            set
            {
                this._mProgressColor = value;
            }
        }

        private Color _mProgressTextColor = Color.Black;

        public Color ProgressTextColor
        {
            get
            {
                return _mProgressTextColor;
            }
            set
            {
                _mProgressTextColor = value;
            }
        }
        //C# listview进度条显示
        public int ProgressColumIndex
        {
            set
            {
                _progressIndex = value;
            }
            get
            {
                return _progressIndex;
            }
        }

        int _progressIndex = -1;

        /// <summary>   
        /// 检查是否可以转化为一个浮点数   
        /// </summary>   
        const string Numberstring = "0123456789.";
        private static bool CheckIsFloat(IEnumerable<char> s)
        {
            //C# listview进度条显示
            foreach (char c in s)
            {
                if (Numberstring.IndexOf(c) > -1)
                {
                    continue;
                }
                else
                    return false;
            }
            return true;
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
        }

        //C# listview进度条显示
        private void InitializeComponent()
        {
            //this.OwnerDraw = true;   
            //this.View = View.Details;   
        }

        protected override void OnDrawColumnHeader(
        DrawListViewColumnHeaderEventArgs e)
        {
            e.DrawDefault = true;
            base.OnDrawColumnHeader(e);
        }

        protected override void OnDrawSubItem(
        DrawListViewSubItemEventArgs e)
        {
            if (e.ColumnIndex != this._progressIndex)
            {   //C# listview进度条显示
                e.DrawDefault = true;
                base.OnDrawSubItem(e);
            }
            else
            {
                if (CheckIsFloat(e.Item.SubItems[e.ColumnIndex].Text))
                //判断当前subitem文本是否可以转为浮点数   
                {
                    float per = float.Parse(e.Item.
                    SubItems[e.ColumnIndex].Text);
                    if (per >= 1.0f)
                    {
                        per = per / 100.0f;
                    }
                    Rectangle rect = new Rectangle(e.Bounds.X,
                     e.Bounds.Y, e.Bounds.Width, e.Bounds.Height);
                    DrawProgress(rect, per, e.Graphics);
                }
            }
        }
        

        ///绘制进度条列的subitem  

        private void DrawProgress(Rectangle rect, float percent, Graphics g)
        {
            if (rect.Height > 2 && rect.Width > 2)
            {
                if ((rect.Top > 0 && rect.Top < this.Height) && (rect.Left > this.Left && rect.Left < this.Width))
                {
                    //绘制进度   
                    int width = (int)(rect.Width * percent);
                    Rectangle newRect = new Rectangle(rect.Left + 1,
                    rect.Top + 1, width - 2, rect.Height - 2);
                    using (Brush tmpb =
                    new SolidBrush(this._mProgressColor))
                    {
                        g.FillRectangle(tmpb, newRect);
                    }

                    newRect = new Rectangle(rect.Left +
                     1, rect.Top + 1, rect.Width - 2,
                     rect.Height - 2);
                    g.DrawRectangle(Pens.RoyalBlue, newRect);

                    StringFormat sf = new StringFormat();
                    sf.Alignment = StringAlignment.Center;
                    sf.LineAlignment = StringAlignment.Center;
                    sf.Trimming = StringTrimming.EllipsisCharacter;

                    newRect = new Rectangle(rect.Left + 1,
                    rect.Top + 1, rect.Width - 2,
                    rect.Height - 2);

                    using (Brush b =
                    new SolidBrush(_mProgressTextColor))
                    {
                        g.DrawString(
                        percent.ToString("p1"), this.Font, b, newRect, sf);
                    }
                }
            }
            //C# listview进度条显示
            else
            {
                return;
            }
        }
        #endregion
    }
}